package com.wintrisstech.iaroc.irobot;

import java.io.IOException;

public class IRobotCreateSensorState {
    protected Boolean trueConstant = Boolean.TRUE;
    protected Boolean falseConstant = Boolean.FALSE;
    
    protected int hysteresis;
    protected int cliffSignalHysteresis;
    protected IRobotCreateSensorState clonedState;
    protected IRobotCreateSensorEventHandler interfaceEventHandler;
    protected IRobotCreateSensorEventHandler nullUserEventHandler;
    
    protected int accumulatedAngle;
    protected int accumulatedDistance;
    protected Boolean advanceButton;
    protected int batteryCapacity;
    protected boolean batteryCapacityUpdated;
    protected int batteryCharge;
    protected boolean batteryChargeUpdated;
    protected int batteryTemperature;
    protected boolean batteryTemperatureUpdated;
    protected Boolean bumpLeft;
    protected Boolean bumpRight;
    protected int cargoBayAnalogSignal;
    protected boolean cargoBayAnalogSignalUpdated;
    protected Boolean cargoBayDigitalInput0;
    protected Boolean cargoBayDigitalInput1;
    protected Boolean cargoBayDigitalInput2;
    protected Boolean cargoBayDigitalInput3;
    protected Boolean cargoBayDeviceDetectBaudRateChange;
    protected int chargingState;
    protected boolean chargingStateUpdated;
    protected int cliffFrontLeftSignal;
    protected boolean cliffFrontLeftSignalUpdated;
    protected int cliffFrontRightSignal;
    protected boolean cliffFrontRightSignalUpdated;
    protected int cliffRightSignal;
    protected boolean cliffRightSignalUpdated;
    protected Boolean cliffFrontLeft;
    protected Boolean cliffFrontRight;
    protected Boolean cliffLeft;
    protected int cliffLeftSignal;
    protected boolean cliffLeftSignalUpdated;
    protected Boolean cliffRight;
    protected int current;
    protected boolean currentUpdated;
    protected Boolean homeBaseChargerAvailable;
    protected int infraredByte;
    protected boolean infraredByteUpdated;
    protected Boolean internalChargerAvailable;
    protected int angle;
    protected boolean angleUpdated;
    protected int distance;
    protected boolean distanceUpdated;
    protected Boolean lowSideDriver0Overcurrent;
    protected Boolean lowSideDriver1Overcurrent;
    protected Boolean lowSideDriver2Overcurrent;
    protected Boolean leftWheelOvercurrent;
    protected int numberOfStreamPackets;
    protected boolean numberOfStreamPacketsUpdated;
    protected int oiMode;
    protected boolean oiModeUpdated;
    protected Boolean playButton;
    protected int requestedLeftVelocity;
    protected boolean requestedLeftVelocityUpdated;
    protected int requestedRadius;
    protected boolean requestedRadiusUpdated;
    protected int requestedRightVelocity;
    protected boolean requestedRightVelocityUpdated;
    protected int requestedVelocity;
    protected boolean requestedVelocityUpdated;
    protected Boolean rightWheelOvercurrent;
    protected int songNumber;
    protected boolean songNumberUpdated;
    protected Boolean songPlaying;
    protected Boolean virtualWall;
    protected int voltage;
    protected boolean voltageUpdated;
    protected Boolean wall;
    protected int wallSignal;
    protected boolean wallSignalUpdated;
    protected Boolean wheelDropCaster;
    protected Boolean wheelDropLeft;
    protected Boolean wheelDropRight;
    
    public IRobotCreateSensorState() {
        initNullEventHandler();
        hysteresis = 2;
        cliffSignalHysteresis = 50;
        initInterfaceEventHandler();
        initClonedState();
    }
    
    protected IRobotCreateSensorState(IRobotCreateSensorState clonedState) {
        this.clonedState = clonedState;
    }
    
    protected void initClonedState() {
        clonedState = new IRobotCreateSensorState(null);
    }

    protected void initNullEventHandler() {
        nullUserEventHandler = new IRobotCreateSensorEventHandler();
    }

    protected void initInterfaceEventHandler() {
        interfaceEventHandler = new IRobotCreateSensorEventHandler();
    }

    public int accumulatedAngle() {
        return checkUpdated(accumulatedAngle, angleUpdated);
    };
    
    public int accumulatedDistance() {
        return checkUpdated(accumulatedDistance, distanceUpdated);
    };

    
    public boolean advanceButton() {
        return checkTriState(advanceButton);
    };

    public int batteryCapacity() {
        return checkUpdated(batteryCapacity, batteryCapacityUpdated);
    };

    
    public int batteryCharge() {
        return checkUpdated(batteryCharge, batteryChargeUpdated);
    };

    
    public int batteryTemperature() {
        return checkUpdated(batteryTemperature, batteryTemperatureUpdated);
    };

    
    public boolean bumpLeft() {
        return checkTriState(bumpLeft);
    };

    
    public boolean bumpRight() {
        return checkTriState(bumpRight);
    };

    
    public int cargoBayAnalogSignal() {
        return checkUpdated(cargoBayAnalogSignal, cargoBayAnalogSignalUpdated);
    };

    
    public boolean cargoBayDigitalInput0() {
        return checkTriState(cargoBayDigitalInput0);
    };

    
    public boolean cargoBayDigitalInput1() {
        return checkTriState(cargoBayDigitalInput1);
    };

    
    public boolean cargoBayDigitalInput2() {
        return checkTriState(cargoBayDigitalInput2);
    };

    
    public boolean cargoBayDigitalInput3() {
        return checkTriState(cargoBayDigitalInput3);
    };

    
    public boolean cargoBayDeviceDetectBaudRateChange() {
        return checkTriState(cargoBayDeviceDetectBaudRateChange);
    };

    
    public int chargingState() {
        return checkUpdated(chargingState, chargingStateUpdated);
    };

    
    public int cliffFrontLeftSignal() {
        return checkUpdated(cliffFrontLeftSignal, cliffFrontLeftSignalUpdated);
    };

    
    public int cliffFrontRightSignal() {
        return checkUpdated(cliffFrontRightSignal, cliffFrontRightSignalUpdated);
    };

    
    public int cliffRightSignal() {
        return checkUpdated(cliffRightSignal, cliffRightSignalUpdated);
    };

    
    public boolean cliffFrontLeft() {
        return checkTriState(cliffFrontLeft);
    };

    
    public boolean cliffFrontRight() {
        return checkTriState(cliffFrontRight);
    };

    
    public boolean cliffLeft() {
        return checkTriState(cliffLeft);
    };

    
    public int cliffLeftSignal() {
        return checkUpdated(cliffLeftSignal, cliffLeftSignalUpdated);
    };

    
    public boolean cliffRight() {
        return checkTriState(cliffRight);
    };

    
    public int current() {
        return checkUpdated(current, currentUpdated);
    };

    
    public boolean homeBaseChargerAvailable() {
        return checkTriState(homeBaseChargerAvailable);
    };

    
    public int infraredByte() {
        return checkUpdated(infraredByte, infraredByteUpdated);
    };

    
    public boolean internalChargerAvailable() {
        return checkTriState(internalChargerAvailable);
    };

    
    public int angle() {
        return checkUpdated(angle, angleUpdated);
    };

    
    public int distance() {
        return checkUpdated(distance, distanceUpdated);
    };

    
    public boolean lowSideDriver0Overcurrent() {
        return checkTriState(lowSideDriver0Overcurrent);
    };

    
    public boolean lowSideDriver1Overcurrent() {
        return checkTriState(lowSideDriver1Overcurrent);
    };

    
    public boolean lowSideDriver2Overcurrent() {
        return checkTriState(lowSideDriver2Overcurrent);
    };

    
    public boolean leftWheelOvercurrent() {
        return checkTriState(leftWheelOvercurrent);
    };

    
    public int numberOfStreamPackets() {
        return checkUpdated(numberOfStreamPackets, numberOfStreamPacketsUpdated);
    };

    
    public int oiMode() {
        return checkUpdated(oiMode, oiModeUpdated);
    };

    
    public boolean playButton() {
        return checkTriState(playButton);
    };

    
    public int requestedLeftVelocity() {
        return checkUpdated(requestedLeftVelocity, requestedLeftVelocityUpdated);
    };

    
    public int requestedRadius() {
        return checkUpdated(requestedRadius, requestedRadiusUpdated);
    };

    
    public int requestedRightVelocity() {
        return checkUpdated(requestedRightVelocity, requestedRightVelocityUpdated);
    };

    
    public int requestedVelocity() {
        return checkUpdated(requestedVelocity, requestedVelocityUpdated);
    };

    
    public boolean rightWheelOvercurrent() {
        return checkTriState(rightWheelOvercurrent);
    };

    
    public int songNumber() {
        return checkUpdated(songNumber, songNumberUpdated);
    };

    
    public boolean songPlaying() {
        return checkTriState(songPlaying);
    };

    
    public boolean virtualWall() {
        return checkTriState(virtualWall);
    };

    
    public int voltage() {
        return checkUpdated(voltage, voltageUpdated);
    };

    
    public boolean wall() {
        return checkTriState(wall);
    };

    
    public int wallSignal() {
        return checkUpdated(wallSignal, wallSignalUpdated);
    };

    
    public boolean wheelDropCaster() {
        return checkTriState(wheelDropCaster);
    };

    
    public boolean wheelDropLeft() {
        return checkTriState(wheelDropLeft);
    };

    
    public boolean wheelDropRight() {
        return checkTriState(wheelDropRight);
    };

    
    protected void resetUpdateState() {
        advanceButton = null;
        batteryCapacityUpdated = false;
        batteryChargeUpdated = false;
        batteryTemperatureUpdated = false;
        bumpLeft = null;
        bumpRight = null;
        cargoBayAnalogSignalUpdated = false;
        chargingStateUpdated = false;
        cliffFrontLeftSignalUpdated = false;
        cliffFrontRightSignalUpdated = false;
        cliffRightSignalUpdated = false;
        cliffFrontLeft = null;
        cliffFrontRight = null;
        cliffLeft = null;
        cliffLeftSignalUpdated = false;
        cliffRight = null;
        currentUpdated = false;
        homeBaseChargerAvailable = null;
        infraredByteUpdated = false;
        internalChargerAvailable = null;
        angleUpdated = false;
        distanceUpdated = false;
        lowSideDriver0Overcurrent = null;
        lowSideDriver1Overcurrent = null;
        lowSideDriver2Overcurrent = null;
        leftWheelOvercurrent = null;
        numberOfStreamPacketsUpdated = false;
        oiModeUpdated = false;
        playButton = null;
        requestedLeftVelocityUpdated = false;
        requestedRadiusUpdated = false;
        requestedRightVelocityUpdated = false;
        requestedVelocityUpdated = false;
        rightWheelOvercurrent = null;
        songNumberUpdated = false;
        songPlaying = null;
        virtualWall = null;
        voltageUpdated = false;
        wall = null;
        wallSignalUpdated = false;
        wheelDropCaster = null;
        wheelDropLeft = null;
        wheelDropRight = null;
    }
    
    public void update(int sensorPacketId, IRobotCreateSerialConnection serialConnection, IRobotCreateSensorEventHandler userEventHandler) throws IOException {
        resetUpdateState();
        if (userEventHandler == null) {
            userEventHandler = nullUserEventHandler;
        }
        updatePrim(sensorPacketId, serialConnection, userEventHandler);
    }
    
    public void update(int[] sensorPacketIds, IRobotCreateSerialConnection serialConnection, IRobotCreateSensorEventHandler userEventHandler) throws IOException {
        resetUpdateState();
        if (userEventHandler == null) {
            userEventHandler = nullUserEventHandler;
        }
        for (int i=0, length = sensorPacketIds.length; i < length; i++) {
            updatePrim(sensorPacketIds[i], serialConnection, userEventHandler);
        }
    }
    
    public void updatePrim(int sensorPacketId, IRobotCreateSerialConnection serialConnection, IRobotCreateSensorEventHandler userEventHandler) throws IOException {
        int dataByte, dataWord;
        
        switch (sensorPacketId) {
        case IRobotCreateConstants.SENSORS_GROUP_ID0:
            updatePrim(IRobotCreateConstants.SENSORS_BUMPS_AND_WHEEL_DROPS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VIRTUAL_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_LOWS_SIDE_DRIVER_AND_WHEEL_OVERCURRENTS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED1, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED2, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_INFRARED_BYTE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BUTTONS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_DISTANCE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_ANGLE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CHARGING_STATE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VOLTAGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CURRENT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_TEMPERATURE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CHARGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CAPACITY, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID1:
            updatePrim(IRobotCreateConstants.SENSORS_BUMPS_AND_WHEEL_DROPS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VIRTUAL_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_LOWS_SIDE_DRIVER_AND_WHEEL_OVERCURRENTS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED1, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED2, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID2:
            updatePrim(IRobotCreateConstants.SENSORS_INFRARED_BYTE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BUTTONS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_DISTANCE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_ANGLE, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID3:
            updatePrim(IRobotCreateConstants.SENSORS_CHARGING_STATE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VOLTAGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CURRENT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_TEMPERATURE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CHARGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CAPACITY, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID4:
            updatePrim(IRobotCreateConstants.SENSORS_WALL_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_LEFT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_RIGHT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CARGO_BAY_DIGITAL_INPUTS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CARGO_BAY_ANALOG_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CHARGING_SOURCES_AVAILABLE, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID5:
            updatePrim(IRobotCreateConstants.SENSORS_OI_MODE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_SONG_NUMBER, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_SONG_PLAYING, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_NUMBER_OF_STREAM_PACKETS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_VELOCITY, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_RADIUS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_RIGHT_VELOCITY, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_LEFT_VELOCITY, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_GROUP_ID6:
            updatePrim(IRobotCreateConstants.SENSORS_BUMPS_AND_WHEEL_DROPS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_RIGHT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VIRTUAL_WALL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_LOWS_SIDE_DRIVER_AND_WHEEL_OVERCURRENTS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED1, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_UNUSED2, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_INFRARED_BYTE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BUTTONS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_DISTANCE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_ANGLE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CHARGING_STATE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_VOLTAGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CURRENT, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_TEMPERATURE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CHARGE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_BATTERY_CAPACITY, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_WALL_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_LEFT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CLIFF_RIGHT_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CARGO_BAY_DIGITAL_INPUTS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CARGO_BAY_ANALOG_SIGNAL, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_CHARGING_SOURCES_AVAILABLE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_OI_MODE, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_SONG_NUMBER, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_SONG_PLAYING, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_NUMBER_OF_STREAM_PACKETS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_VELOCITY, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_RADIUS, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_RIGHT_VELOCITY, serialConnection, userEventHandler);
            updatePrim(IRobotCreateConstants.SENSORS_REQUESTED_LEFT_VELOCITY, serialConnection, userEventHandler);
            break;
        case IRobotCreateConstants.SENSORS_BUMPS_AND_WHEEL_DROPS:
            dataByte = serialConnection.readUnsignedByte();
            bumpRight = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.bumpRight != bumpRight) {
                interfaceEventHandler.bumpRightEvent(clonedState.bumpRight, bumpRight);
                userEventHandler.bumpRightEvent(clonedState.bumpRight, bumpRight);
                clonedState.bumpRight = bumpRight;
            }
            bumpLeft = (dataByte & 0x02) != 0 ? trueConstant:falseConstant;
            if (clonedState.bumpLeft != bumpLeft) {
                interfaceEventHandler.bumpLeftEvent(clonedState.bumpLeft, bumpLeft);
                userEventHandler.bumpLeftEvent(clonedState.bumpLeft, bumpLeft);
                clonedState.bumpLeft = bumpLeft;
            }
            wheelDropRight = (dataByte & 0x04) != 0 ? trueConstant:falseConstant;
            if (clonedState.wheelDropRight != wheelDropRight) {
                interfaceEventHandler.wheelDropRightEvent(clonedState.wheelDropRight, wheelDropRight);
                userEventHandler.wheelDropRightEvent(clonedState.wheelDropRight, wheelDropRight);
                clonedState.wheelDropRight = wheelDropRight;
            }
            wheelDropLeft = (dataByte & 0x08) != 0 ? trueConstant:falseConstant;
            if (clonedState.wheelDropLeft != wheelDropLeft) {
                interfaceEventHandler.wheelDropLeftEvent(clonedState.wheelDropLeft, wheelDropLeft);
                userEventHandler.wheelDropLeftEvent(clonedState.wheelDropLeft, wheelDropLeft);
                clonedState.wheelDropLeft = wheelDropLeft;
            }
            wheelDropCaster = (dataByte & 0x10) != 0 ? trueConstant:falseConstant;
            if (clonedState.wheelDropCaster != wheelDropCaster) {
                interfaceEventHandler.wheelDropCaster(clonedState.wheelDropCaster, wheelDropCaster);
                userEventHandler.wheelDropCaster(clonedState.wheelDropCaster, wheelDropCaster);
            }
            break;
        case IRobotCreateConstants.SENSORS_WALL:
            dataByte = serialConnection.readUnsignedByte();
            wall = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.wall != wall) {
                interfaceEventHandler.wallEvent(clonedState.wall, wall);
                userEventHandler.wallEvent(clonedState.wall, wall);
                clonedState.wall = wall;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_LEFT:
            dataByte = serialConnection.readUnsignedByte();
            cliffLeft = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.cliffLeft != cliffLeft) {
                interfaceEventHandler.cliffLeftEvent(clonedState.cliffLeft, cliffLeft);
                userEventHandler.cliffLeftEvent(clonedState.cliffLeft, cliffLeft);
                clonedState.cliffLeft = cliffLeft;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT:
            dataByte = serialConnection.readUnsignedByte();
            cliffFrontLeft = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.cliffFrontLeft != cliffFrontLeft) {
                interfaceEventHandler.cliffFrontLeftEvent(clonedState.cliffFrontLeft, cliffFrontLeft);
                userEventHandler.cliffFrontLeftEvent(clonedState.cliffFrontLeft, cliffFrontLeft);
                clonedState.cliffFrontLeft = cliffFrontLeft;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT:
            dataByte = serialConnection.readUnsignedByte();
            cliffFrontRight = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.cliffFrontRight != cliffFrontRight) {
                interfaceEventHandler.cliffFrontRightEvent(clonedState.cliffFrontRight, cliffFrontRight);
                userEventHandler.cliffFrontRightEvent(clonedState.cliffFrontRight, cliffFrontRight);
                clonedState.cliffFrontRight = cliffFrontRight;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_RIGHT:
            dataByte = serialConnection.readUnsignedByte();
            cliffRight = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.cliffRight != cliffRight) {
                interfaceEventHandler.cliffRightEvent(clonedState.cliffRight, cliffRight);
                userEventHandler.cliffRightEvent(clonedState.cliffRight, cliffRight);
                clonedState.cliffRight = cliffRight;
            }
            break;
        case IRobotCreateConstants.SENSORS_VIRTUAL_WALL:
            dataByte = serialConnection.readUnsignedByte();
            virtualWall = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.virtualWall != virtualWall) {
                interfaceEventHandler.virtualWallEvent(clonedState.virtualWall, virtualWall);
                userEventHandler.virtualWallEvent(clonedState.virtualWall, virtualWall);
                clonedState.virtualWall = virtualWall;
            }
            break;
        case IRobotCreateConstants.SENSORS_LOWS_SIDE_DRIVER_AND_WHEEL_OVERCURRENTS:
            dataByte = serialConnection.readUnsignedByte();
            lowSideDriver0Overcurrent = (dataByte & 0x02) != 0 ? trueConstant:falseConstant;
            if (clonedState.lowSideDriver0Overcurrent != lowSideDriver0Overcurrent) {
                interfaceEventHandler.lowSideDriver0OvercurrentEvent(clonedState.lowSideDriver0Overcurrent, lowSideDriver0Overcurrent);
                userEventHandler.lowSideDriver0OvercurrentEvent(clonedState.lowSideDriver0Overcurrent, lowSideDriver0Overcurrent);
                clonedState.lowSideDriver0Overcurrent = lowSideDriver0Overcurrent;
            }
            lowSideDriver1Overcurrent = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.lowSideDriver1Overcurrent != lowSideDriver1Overcurrent) {
                interfaceEventHandler.lowSideDriver1OvercurrentEvent(clonedState.lowSideDriver1Overcurrent, lowSideDriver1Overcurrent);
                userEventHandler.lowSideDriver1OvercurrentEvent(clonedState.lowSideDriver1Overcurrent, lowSideDriver1Overcurrent);
                clonedState.lowSideDriver1Overcurrent = lowSideDriver1Overcurrent;
            }
            lowSideDriver2Overcurrent = (dataByte & 0x04) != 0 ? trueConstant:falseConstant;
            if (clonedState.lowSideDriver2Overcurrent != lowSideDriver2Overcurrent) {
                interfaceEventHandler.lowSideDriver2OvercurrentEvent(clonedState.lowSideDriver2Overcurrent, lowSideDriver2Overcurrent);
                userEventHandler.lowSideDriver2OvercurrentEvent(clonedState.lowSideDriver2Overcurrent, lowSideDriver2Overcurrent);
                clonedState.lowSideDriver2Overcurrent = lowSideDriver2Overcurrent;
            }
            rightWheelOvercurrent = (dataByte & 0x08) != 0 ? trueConstant:falseConstant;
            if (clonedState.rightWheelOvercurrent != rightWheelOvercurrent) {
                interfaceEventHandler.rightWheelOvercurrentEvent(clonedState.rightWheelOvercurrent, rightWheelOvercurrent);
                userEventHandler.rightWheelOvercurrentEvent(clonedState.rightWheelOvercurrent, rightWheelOvercurrent);
                clonedState.rightWheelOvercurrent = rightWheelOvercurrent;
            }
            leftWheelOvercurrent = (dataByte & 0x10) != 0 ? trueConstant:falseConstant;
            if (clonedState.leftWheelOvercurrent != leftWheelOvercurrent) {
                interfaceEventHandler.leftWheelOvercurrentEvent(clonedState.leftWheelOvercurrent, leftWheelOvercurrent);
                userEventHandler.leftWheelOvercurrentEvent(clonedState.leftWheelOvercurrent, leftWheelOvercurrent);
                clonedState.leftWheelOvercurrent = leftWheelOvercurrent;
            }
            break;
        case IRobotCreateConstants.SENSORS_UNUSED1:
            serialConnection.readUnsignedByte();
            break;
        case IRobotCreateConstants.SENSORS_UNUSED2:
            serialConnection.readUnsignedByte();
            break;
        case IRobotCreateConstants.SENSORS_INFRARED_BYTE:
            dataByte = serialConnection.readUnsignedByte();
            infraredByte = dataByte;
            infraredByteUpdated = true;
            if (clonedState.infraredByte != infraredByte) {
                interfaceEventHandler.infraredByteEvent(clonedState.infraredByte, infraredByte);
                userEventHandler.infraredByteEvent(clonedState.infraredByte, infraredByte);
                clonedState.infraredByte = infraredByte;
            }
            break;
        case IRobotCreateConstants.SENSORS_BUTTONS:
            dataByte = serialConnection.readUnsignedByte();
            playButton = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.playButton != playButton) {
                interfaceEventHandler.playButtonEvent(clonedState.playButton, playButton);
                userEventHandler.playButtonEvent(clonedState.playButton, playButton);
                clonedState.playButton = playButton;
            }
            advanceButton = (dataByte & 0x04) != 0 ? trueConstant:falseConstant;
            if (clonedState.advanceButton != advanceButton) {
                interfaceEventHandler.advanceButtonEvent(clonedState.advanceButton, advanceButton);
                userEventHandler.advanceButtonEvent(clonedState.advanceButton, advanceButton);
                clonedState.advanceButton = advanceButton;
            }
            break;
        case IRobotCreateConstants.SENSORS_DISTANCE:
            dataWord = serialConnection.readSignedWord();
            distance = dataWord;
            distanceUpdated = true;
            if (dataWord == -32768) {
                accumulatedDistance = Integer.MIN_VALUE;
            } else if (dataWord == 32767) {
                accumulatedDistance = Integer.MAX_VALUE;
            } else {
                accumulatedDistance += dataWord;
            }
            if (Math.abs(clonedState.distance - distance) > hysteresis) {
                interfaceEventHandler.distanceEvent(clonedState.distance, distance);
                userEventHandler.distanceEvent(clonedState.distance, distance);
                clonedState.distance = distance;
            }
            break;
        case IRobotCreateConstants.SENSORS_ANGLE:
            dataWord = serialConnection.readSignedWord();
            angle = dataWord;
            angleUpdated = true;
            if (dataWord == -32768) {
                accumulatedAngle = Integer.MIN_VALUE;
            } else if (dataWord == 32767) {
                accumulatedAngle = Integer.MAX_VALUE;
            } else {
                accumulatedAngle += dataWord;
            }
            if (Math.abs(clonedState.angle - angle) > hysteresis) {
                interfaceEventHandler.angleEvent(clonedState.angle, angle);
                userEventHandler.angleEvent(clonedState.angle, angle);
                clonedState.angle = angle;
            }
            break;
        case IRobotCreateConstants.SENSORS_CHARGING_STATE:
            dataByte = serialConnection.readUnsignedByte();
            chargingState = dataByte;
            chargingStateUpdated = true;
            if (clonedState.chargingState != chargingState) {
                interfaceEventHandler.chargingStateEvent(clonedState.chargingState, chargingState);
                userEventHandler.chargingStateEvent(clonedState.chargingState, chargingState);
                clonedState.chargingState = chargingState;
            }
            break;
        case IRobotCreateConstants.SENSORS_VOLTAGE:
            voltage = serialConnection.readUnsignedWord();
            voltageUpdated = true;
            if (clonedState.voltage != voltage) {
                interfaceEventHandler.voltageEvent(clonedState.voltage, voltage);
                userEventHandler.voltageEvent(clonedState.voltage, voltage);
                clonedState.voltage = voltage;
            }
            break;
        case IRobotCreateConstants.SENSORS_CURRENT:
            current = serialConnection.readSignedWord();
            currentUpdated = true;
            if (clonedState.current != current) {
                interfaceEventHandler.currentEvent(clonedState.current, current);
                userEventHandler.currentEvent(clonedState.current, current);
                clonedState.current = current;
            }
            break;
        case IRobotCreateConstants.SENSORS_BATTERY_TEMPERATURE:
            batteryTemperature = serialConnection.readSignedByte();
            batteryTemperatureUpdated = true;
            if (clonedState.batteryTemperature != batteryTemperature) {
                interfaceEventHandler.batteryTemperatureEvent(clonedState.batteryTemperature, batteryTemperature);
                userEventHandler.batteryTemperatureEvent(clonedState.batteryTemperature, batteryTemperature);
                clonedState.batteryTemperature = batteryTemperature;
            }
            break;
        case IRobotCreateConstants.SENSORS_BATTERY_CHARGE:
            batteryCharge = serialConnection.readUnsignedWord();
            batteryChargeUpdated = true;
            if (clonedState.batteryCharge != batteryCharge) {
                interfaceEventHandler.batteryChargeEvent(clonedState.batteryCharge, batteryCharge);
                userEventHandler.batteryChargeEvent(clonedState.batteryCharge, batteryCharge);
                clonedState.batteryCharge = batteryCharge;
            }
            break;
        case IRobotCreateConstants.SENSORS_BATTERY_CAPACITY:
            batteryCapacity = serialConnection.readUnsignedWord();
            batteryCapacityUpdated = true;
            if (clonedState.batteryCapacity != batteryCapacity) {
                interfaceEventHandler.batteryCapacityEvent(clonedState.batteryCapacity, batteryCapacity);
                userEventHandler.batteryCapacityEvent(clonedState.batteryCapacity, batteryCapacity);
                clonedState.batteryCapacity = batteryCapacity;
            }
            break;
        case IRobotCreateConstants.SENSORS_WALL_SIGNAL:
            wallSignal = serialConnection.readUnsignedWord();
            wallSignalUpdated = true;
            if (Math.abs(clonedState.wallSignal - wallSignal) > hysteresis) {
                interfaceEventHandler.wallSignalEvent(clonedState.wallSignal, wallSignal);
                userEventHandler.wallSignalEvent(clonedState.wallSignal, wallSignal);
                clonedState.wallSignal = wallSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_LEFT_SIGNAL:
            cliffLeftSignal = serialConnection.readUnsignedWord();
            cliffLeftSignalUpdated = true;
            if (Math.abs(clonedState.cliffLeftSignal - cliffLeftSignal) > cliffSignalHysteresis) {
                interfaceEventHandler.cliffLeftSignalEvent(clonedState.cliffLeftSignal, cliffLeftSignal);
                userEventHandler.cliffLeftSignalEvent(clonedState.cliffLeftSignal, cliffLeftSignal);
                clonedState.cliffLeftSignal = cliffLeftSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_FRONT_LEFT_SIGNAL:
            cliffFrontLeftSignal = serialConnection.readUnsignedWord();
            cliffFrontLeftSignalUpdated = true;
            if (Math.abs(clonedState.cliffFrontLeftSignal - cliffFrontLeftSignal) > cliffSignalHysteresis) {
                interfaceEventHandler.cliffFrontLeftSignalEvent(clonedState.cliffFrontLeftSignal, cliffFrontLeftSignal);
                userEventHandler.cliffFrontLeftSignalEvent(clonedState.cliffFrontLeftSignal, cliffFrontLeftSignal);
                clonedState.cliffFrontLeftSignal = cliffFrontLeftSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_FRONT_RIGHT_SIGNAL:
            cliffFrontRightSignal = serialConnection.readUnsignedWord();
            cliffFrontRightSignalUpdated = true;
            if (Math.abs(clonedState.cliffFrontRightSignal - cliffFrontRightSignal) > cliffSignalHysteresis) {
                interfaceEventHandler.cliffFrontRightSignalEvent(clonedState.cliffFrontRightSignal, cliffFrontRightSignal);
                userEventHandler.cliffFrontRightSignalEvent(clonedState.cliffFrontRightSignal, cliffFrontRightSignal);
                clonedState.cliffFrontRightSignal = cliffFrontRightSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CLIFF_RIGHT_SIGNAL:
            cliffRightSignal = serialConnection.readUnsignedWord();
            cliffRightSignalUpdated = true;
            if (Math.abs(clonedState.cliffRightSignal - cliffRightSignal) > cliffSignalHysteresis) {
                interfaceEventHandler.cliffRightSignalEvent(clonedState.cliffRightSignal, cliffRightSignal);
                userEventHandler.cliffRightSignalEvent(clonedState.cliffRightSignal, cliffRightSignal);
                clonedState.cliffRightSignal = cliffRightSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CARGO_BAY_DIGITAL_INPUTS:
            dataByte = serialConnection.readUnsignedByte();
            cargoBayDigitalInput0 = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.cargoBayDigitalInput0 != cargoBayDigitalInput0) {
                interfaceEventHandler.cargoBayDigitalInput0Event(clonedState.cargoBayDigitalInput0, cargoBayDigitalInput0);
                userEventHandler.cargoBayDigitalInput0Event(clonedState.cargoBayDigitalInput0, cargoBayDigitalInput0);
                clonedState.cargoBayDigitalInput0 = cargoBayDigitalInput0;
            }
            cargoBayDigitalInput1 = (dataByte & 0x02) != 0 ? trueConstant:falseConstant;
            if (clonedState.cargoBayDigitalInput1 != cargoBayDigitalInput1) {
                interfaceEventHandler.cargoBayDigitalInput1Event(clonedState.cargoBayDigitalInput1, cargoBayDigitalInput1);
                userEventHandler.cargoBayDigitalInput1Event(clonedState.cargoBayDigitalInput1, cargoBayDigitalInput1);
                clonedState.cargoBayDigitalInput1 = cargoBayDigitalInput1;
            }
            cargoBayDigitalInput2 = (dataByte & 0x04) != 0 ? trueConstant:falseConstant;
            if (clonedState.cargoBayDigitalInput2 != cargoBayDigitalInput2) {
                interfaceEventHandler.cargoBayDigitalInput2Event(clonedState.cargoBayDigitalInput2, cargoBayDigitalInput2);
                userEventHandler.cargoBayDigitalInput2Event(clonedState.cargoBayDigitalInput2, cargoBayDigitalInput2);
                clonedState.cargoBayDigitalInput2 = cargoBayDigitalInput2;
            }
            cargoBayDigitalInput3 = (dataByte & 0x08) != 0 ? trueConstant:falseConstant;
            if (clonedState.cargoBayDigitalInput3 != cargoBayDigitalInput3) {
                interfaceEventHandler.cargoBayDigitalInput3Event(clonedState.cargoBayDigitalInput3, cargoBayDigitalInput3);
                userEventHandler.cargoBayDigitalInput3Event(clonedState.cargoBayDigitalInput3, cargoBayDigitalInput3);
                clonedState.cargoBayDigitalInput3 = cargoBayDigitalInput3;
            }
            cargoBayDeviceDetectBaudRateChange = (dataByte & 0x10) != 0 ? trueConstant:falseConstant;
            if (clonedState.cargoBayDeviceDetectBaudRateChange != cargoBayDeviceDetectBaudRateChange) {
                interfaceEventHandler.cargoBayDeviceDetectBaudRateChangeEvent(clonedState.cargoBayDeviceDetectBaudRateChange, cargoBayDeviceDetectBaudRateChange);
                userEventHandler.cargoBayDeviceDetectBaudRateChangeEvent(clonedState.cargoBayDeviceDetectBaudRateChange, cargoBayDeviceDetectBaudRateChange);
                clonedState.cargoBayDeviceDetectBaudRateChange = cargoBayDeviceDetectBaudRateChange;
            }
            break;
        case IRobotCreateConstants.SENSORS_CARGO_BAY_ANALOG_SIGNAL:
            cargoBayAnalogSignal = serialConnection.readUnsignedWord();
            cargoBayAnalogSignalUpdated = true;;
            if (Math.abs(clonedState.cargoBayAnalogSignal - cargoBayAnalogSignal) > hysteresis) {
                interfaceEventHandler.cargoBayAnalogSignalEvent(clonedState.cargoBayAnalogSignal, cargoBayAnalogSignal);
                userEventHandler.cargoBayAnalogSignalEvent(clonedState.cargoBayAnalogSignal, cargoBayAnalogSignal);
                clonedState.cargoBayAnalogSignal = cargoBayAnalogSignal;
            }
            break;
        case IRobotCreateConstants.SENSORS_CHARGING_SOURCES_AVAILABLE:
            dataByte = serialConnection.readUnsignedByte();
            internalChargerAvailable = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.internalChargerAvailable != internalChargerAvailable) {
                interfaceEventHandler.internalChargerAvailableEvent(clonedState.internalChargerAvailable, internalChargerAvailable);
                userEventHandler.internalChargerAvailableEvent(clonedState.internalChargerAvailable, internalChargerAvailable);
                clonedState.internalChargerAvailable = internalChargerAvailable;
            }
            homeBaseChargerAvailable = (dataByte & 0x02) != 0 ? trueConstant:falseConstant;
            if (clonedState.homeBaseChargerAvailable != homeBaseChargerAvailable) {
                interfaceEventHandler.homeBaseChargerAvailableEvent(clonedState.homeBaseChargerAvailable, homeBaseChargerAvailable);
                userEventHandler.homeBaseChargerAvailableEvent(clonedState.homeBaseChargerAvailable, homeBaseChargerAvailable);
                clonedState.homeBaseChargerAvailable = homeBaseChargerAvailable;
            }
            break;
        case IRobotCreateConstants.SENSORS_OI_MODE:
            oiMode = serialConnection.readUnsignedByte();
            oiModeUpdated = true;
            if (clonedState.oiMode != oiMode) {
                interfaceEventHandler.oiModeEvent(clonedState.oiMode, oiMode);
                userEventHandler.oiModeEvent(clonedState.oiMode, oiMode);
                clonedState.oiMode = oiMode;
            }
            break;
        case IRobotCreateConstants.SENSORS_SONG_NUMBER:
            songNumber = serialConnection.readUnsignedByte();
            songNumberUpdated = true;
            if (clonedState.songNumber != songNumber) {
                interfaceEventHandler.songNumberEvent(clonedState.songNumber, songNumber);
                userEventHandler.songNumberEvent(clonedState.songNumber, songNumber);
                clonedState.songNumber = songNumber;
            }
            break;
        case IRobotCreateConstants.SENSORS_SONG_PLAYING:
            dataByte = serialConnection.readUnsignedByte();
            songPlaying = (dataByte & 0x01) != 0 ? trueConstant:falseConstant;
            if (clonedState.songPlaying != songPlaying) {
                interfaceEventHandler.songPlayingEvent(clonedState.songPlaying, songPlaying);
                userEventHandler.songPlayingEvent(clonedState.songPlaying, songPlaying);
                clonedState.songPlaying = songPlaying;
            }
            break;
        case IRobotCreateConstants.SENSORS_NUMBER_OF_STREAM_PACKETS:
            numberOfStreamPackets = serialConnection.readUnsignedByte();
            numberOfStreamPacketsUpdated = true;
            if (clonedState.numberOfStreamPackets != numberOfStreamPackets) {
                interfaceEventHandler.numberOfStreamPacketsEvent(clonedState.numberOfStreamPackets, numberOfStreamPackets);
                userEventHandler.numberOfStreamPacketsEvent(clonedState.numberOfStreamPackets, numberOfStreamPackets);
                clonedState.numberOfStreamPackets = numberOfStreamPackets;
            }
            break;
        case IRobotCreateConstants.SENSORS_REQUESTED_VELOCITY:
            requestedVelocity = serialConnection.readSignedWord();
            requestedVelocityUpdated = true;
            if (clonedState.requestedVelocity != requestedVelocity) {
                interfaceEventHandler.requestedVelocityEvent(clonedState.requestedVelocity, requestedVelocity);
                userEventHandler.requestedVelocityEvent(clonedState.requestedVelocity, requestedVelocity);
                clonedState.requestedVelocity = requestedVelocity;
            }
            break;
        case IRobotCreateConstants.SENSORS_REQUESTED_RADIUS:
            requestedRadius = serialConnection.readSignedWord();
            requestedRadiusUpdated = true;
            if (clonedState.requestedRadius != requestedRadius) {
                interfaceEventHandler.requestedRadiusEvent(clonedState.requestedRadius, requestedRadius);
                userEventHandler.requestedRadiusEvent(clonedState.requestedRadius, requestedRadius);
                clonedState.requestedRadius = requestedRadius;
            }
            break;
        case IRobotCreateConstants.SENSORS_REQUESTED_RIGHT_VELOCITY:
            requestedRightVelocity = serialConnection.readSignedWord();
            requestedRightVelocityUpdated = true;
            if (clonedState.requestedRightVelocity != requestedRightVelocity) {
                interfaceEventHandler.requestedRightVelocityEvent(clonedState.requestedRightVelocity, requestedRightVelocity);
                userEventHandler.requestedRightVelocityEvent(clonedState.requestedRightVelocity, requestedRightVelocity);
                clonedState.requestedRightVelocity = requestedRightVelocity;
            }
            break;
        case IRobotCreateConstants.SENSORS_REQUESTED_LEFT_VELOCITY:
            requestedLeftVelocity = serialConnection.readSignedWord();
            requestedLeftVelocityUpdated = true;
            if (clonedState.requestedLeftVelocity != requestedLeftVelocity) {
                interfaceEventHandler.requestedLeftVelocityEvent(clonedState.requestedLeftVelocity, requestedLeftVelocity);
                userEventHandler.requestedLeftVelocityEvent(clonedState.requestedLeftVelocity, requestedLeftVelocity);
                clonedState.requestedLeftVelocity = requestedLeftVelocity;
            }
            break;
        default:
            throw new IllegalArgumentException(String.valueOf(sensorPacketId));
        }
    }
    
    protected int checkUpdated(int value, boolean updated) {
        if (!updated) {
            throw new IllegalStateException("Dont know the state of the sensor requested");
        }
        return value;
    }
    
    protected boolean checkTriState(Boolean triState) {
        if (triState == null) {
            throw new IllegalStateException("Dont know the state of the sensor requested");
        }
        return triState == trueConstant;
    }
    
    public int getHysteris() {
        return hysteresis;
    }
    
    public int getCliffSignalHysteris() {
        return cliffSignalHysteresis;
    }
    
    public void setCliffSignalHysteresis(int hysteresis) {
        this.cliffSignalHysteresis = hysteresis;
    }

    public void setHysteresis(int hysteresis) {
        this.hysteresis = hysteresis;
    }
    
}
